﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Net;
using System.Windows;
using System.Windows.Media.Imaging;

using Microsoft.WindowsAPICodePack.Dialogs;
using Microsoft.WindowsAPICodePack.Taskbar;


namespace SlideShowDFG2
{
    /// <summary>
    /// Interaction logic for EditSlideWindow.xaml
    /// </summary>
    public partial class EditSlideWindow : Window
    {
        RegistryHelper _registry;

        public EditSlideWindow()
        {
            InitializeComponent();
        }

        Slide _slide;
        string _saveDir;
        FileLocationProtocol _method;
        WebClient _client;

        string _imagePath;
        BitmapFrame _image;

        BackgroundWorker _worker;

        List<Exception> _convertErrors;

        string[] _videoExts = { ".wmv", ".asf" };
        bool _isVideo = false;

        public Slide Slide
        {
            get { return _slide; }
            set { _slide = value; }
        }

        public string SaveDir
        {
            get { return _saveDir; }
            set { _saveDir = value; }
        }

        public FileLocationProtocol Method
        {
            get { return _method; }
            set { _method = value; }
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            if (_slide == null) _slide = new Slide();
            base.DataContext = _slide;

            _registry = new RegistryHelper();

            if (_method == FileLocationProtocol.FTP) _client = WebClientHelper.GetNewInstance();
        }

        private void Window_Closing(object sender, CancelEventArgs e)
        {
            if (_method == FileLocationProtocol.FTP) _client.Dispose();
        }

        private void btnBrowse_Click(object sender, RoutedEventArgs e)
        {
            if (Environment.OSVersion.Version.Major == 6)
            {
                CommonOpenFileDialog dialog = new CommonOpenFileDialog();
                dialog.EnsureFileExists = true;
                dialog.Filters.Add(new CommonFileDialogFilter("Compatible Files", "*.jpg;*.jpeg;*.jpe;*.wmv;*.asf"));
                dialog.Filters.Add(new CommonFileDialogFilter("Image Files", "*.jpg;*.jpeg;*.jpe"));
                dialog.Filters.Add(new CommonFileDialogFilter("Video Files", "*.wmv;*.asf"));
                dialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
                dialog.Multiselect = false;
                dialog.ShowPlacesList = true;
                dialog.Title = "Select Source File";

                if (dialog.ShowDialog() == CommonFileDialogResult.OK)
                {
                    _imagePath = dialog.FileName;
                    tbImageFile.Text = dialog.FileName;

                    string ext = Path.GetExtension(_imagePath);
                    foreach (string videoExt in _videoExts)
                    {
                        if (ext == videoExt)
                        {
                            _isVideo = true;
                                break;
                        }
                    }

                    if (!_isVideo)
                    {
                        BitmapDecoder decoder = BitmapDecoder.Create(new Uri(_imagePath, UriKind.RelativeOrAbsolute),
                                                                        BitmapCreateOptions.None,
                                                                        BitmapCacheOption.Default);
                        _image = decoder.Frames[0];
                        imgPreview.Source = _image;

                        btnMetadataDesc.IsEnabled = true;
                        btnMetadataTitle.IsEnabled = true;
                    }
                }
            }
        }

        private void btnMetadataTitle_Click(object sender, RoutedEventArgs e)
        {
            BitmapMetadata data = _image.Metadata as BitmapMetadata;
            _slide.Title = data.Title;
        }

        private void btnMetadataDesc_Click(object sender, RoutedEventArgs e)
        {
            BitmapMetadata data = _image.Metadata as BitmapMetadata;
            _slide.Description = data.Comment;
        }

        private void btnOkay_Click(object sender, RoutedEventArgs e)
        {
            btnOkay.IsEnabled = false;
            btnCancel.IsEnabled = false;

            pbProgress.IsIndeterminate = true;
            lblStatus.Content = "Working...";

            MainWindow.SetTaskBarState(TaskbarProgressBarState.Indeterminate);

            _convertErrors = new List<Exception>();

            _worker = new BackgroundWorker();
            _worker.WorkerReportsProgress = false;
            _worker.WorkerSupportsCancellation = false;
            _worker.DoWork += new DoWorkEventHandler(_worker_DoWork);
            _worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_worker_RunWorkerCompleted);
            _worker.RunWorkerAsync();
        }

        private void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

            MainWindow.SetTaskBarState(TaskbarProgressBarState.Normal);

            if (e.Error != null)
            {
                if (e.Error is WebException)
                {
                    WebException exception = (WebException)e.Error;
                    MessageBox.Show(exception.Message, "Upload Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }
                else if (e.Error is VideoHelperException)
                {
                    VideoHelperException exception = (VideoHelperException)e.Error;
                    
                }
                else
                {
                    MessageBox.Show("Unspecified Error", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            else
            {
                base.DialogResult = true;
            }
            base.Close();
        }

        private void _worker_DoWork(object sender, DoWorkEventArgs e)
        {
            if (!_isVideo)
            {
                int width = 0, height = 0;
                int resizeSeed = _registry.ResizeSeed;

                ResizeOptions resizeOption = (ResizeOptions)_registry.ResizeOption;

                if (resizeOption == ResizeOptions.ScaleByHeight || resizeOption == ResizeOptions.ScaleByWidth)
                {
                    if (_image.PixelWidth > _image.PixelHeight) // Landscape
                    {
                        if (resizeOption == ResizeOptions.ScaleByWidth)
                        {
                            width = resizeSeed;
                            height = (_image.PixelHeight * width) / _image.PixelWidth;
                        }
                        else
                        {
                            height = resizeSeed;
                            width = (_image.PixelWidth * height) / _image.PixelHeight;
                        }
                    }
                    else if (_image.PixelWidth < _image.PixelHeight) // Potrait
                    {
                        if (resizeOption == ResizeOptions.ScaleByWidth)
                        {
                            height = resizeSeed;
                            width = (_image.PixelHeight * height) / _image.PixelHeight;
                        }
                        else
                        {
                            width = resizeSeed;
                            height = (_image.PixelHeight * width) / _image.PixelWidth;
                        }

                    }
                    else // Square
                    {
                        width = height = resizeSeed;
                    }
                }
                else
                {
                    width = _image.PixelWidth * (resizeSeed / 100);
                    height = _image.PixelHeight * (resizeSeed / 100);
                }

                using (Bitmap resized = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb))
                {
                    using (Graphics grphs = Graphics.FromImage(resized))
                    {
                        grphs.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;
                        Rectangle rect = new Rectangle(0, 0, width, height);
                        grphs.DrawImage(Image.FromFile(_imagePath), rect);
                        if (_registry.EnableWatermark)
                        {
                            StringFormat format = new StringFormat();
                            format.Alignment = StringAlignment.Center;
                            format.LineAlignment = StringAlignment.Center;
                            grphs.DrawString(_registry.WatermarkText, new Font("Arial Black", 28),
                                                new HatchBrush(HatchStyle.LargeConfetti, Color.FromArgb(65, Color.LightGray), Color.FromArgb(80, Color.Gray)),
                                                new RectangleF(new PointF(0, 0), new SizeF((float)width, (float)height)), format);
                        }
                    }
                    _slide.Source = Path.GetFileName(_imagePath);
                    if (_method == FileLocationProtocol.LocalFileSystem)
                    {
                        resized.Save(Path.Combine(_saveDir, Path.GetFileName(_imagePath)));
                    }
                    else
                    {
                        string tempFile = Path.GetTempFileName();
                        resized.Save(tempFile);
                        _client.UploadFile(new Uri(Path.GetFileName(_imagePath), UriKind.Relative), tempFile);
                    }
                }

                if (_registry.CreateThumbnail)
                {
                    using (Bitmap thumbnail = new Bitmap(100, 100, System.Drawing.Imaging.PixelFormat.Format16bppRgb555))
                    {
                        using (Graphics tGrphs = Graphics.FromImage(thumbnail))
                        {
                            tGrphs.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;
                            Rectangle rect = new Rectangle(0, 0, 100, 100);
                            tGrphs.DrawImage(Image.FromFile(_imagePath), rect);
                        }

                        string thumbName = string.Format("{0}_thumb{1}", Path.GetFileNameWithoutExtension(_imagePath), Path.GetExtension(_imagePath));
                        _slide.Thumbnail = thumbName;

                        if (_method == FileLocationProtocol.LocalFileSystem)
                        {
                            thumbnail.Save(Path.Combine(_saveDir, thumbName));
                        }
                        else
                        {
                            string tempFile = Path.GetTempFileName();
                            thumbnail.Save(tempFile);
                            _client.UploadFile(new Uri(thumbName), tempFile);
                        }
                    }
                }
            }
            else
            {
                if (VideoHelper.IsFFMpegInstalled())
                {

                    if (_method == FileLocationProtocol.FTP)
                    {
                        string tempFile = Path.GetTempFileName(); 
                        VideoHelper.ConvertVideo(_imagePath, tempFile);
                        _client.UploadFile(Path.GetFileName(_imagePath), tempFile);
                    }
                    else
                    {
                        VideoHelper.ConvertVideo(_imagePath, Path.Combine(_saveDir, Path.GetFileName(_imagePath)));
                        _slide.Source = Path.GetFileName(_imagePath);
                    }
                }
                else
                {
                    if (_method == FileLocationProtocol.FTP)
                    {
                        _client.UploadFile(Path.GetFileName(_imagePath), _imagePath);
                    }
                    else
                    {
                        File.Copy(_imagePath, Path.Combine(_saveDir, Path.GetFileName(_imagePath)));
                    }
                }
            }
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            base.DialogResult = false;
            base.Close();
        }
    }
}